<?php
namespace GK;
class Curl
{
    public $ch; //curl本体
    private $result_mode=0;//返回数据模式，0=只返回基本数据，1=返回http的header数据，2=返回所有数据
    public $errormsg=[];
    public $proxy='';
    public $proxyport='';    //错误信息
    public function __construct()
    {
        $this->ch=curl_init();  //类初始化时，创建本体
    }
    private function base($url, $headers=[], $mode=false, $data=[], $ssl=false, $timeout=0)
    //基本方法参数说明：
    //$url:请求目标网址
    //$timeout:请求超时时间,默认值0
    //$mode:请求方法[get|post],默认get值false,post=true;
    //$headers:请求http头,索引数组格式
    //$ssl:是否https请求方式
    //$data:post提交数据，关联数组格式
    {
        if (empty($url))
        {
            $this->errormsg[]="url为空！";
            return false;
        }
        curl_setopt($this->ch, CURLOPT_URL,$url);               //设置url参数
        curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION,1);       
        curl_setopt($this->ch, CURLOPT_TIMEOUT,$timeout);       //设置超时
        //设置是否返回http_header
        if ($this->result_mode==0)                              
        {
            curl_setopt($this->ch, CURLOPT_HEADER, 0);
        }
        else
        {
            curl_setopt($this->ch, CURLOPT_HEADER, 1);
            
        }
        //设置是否返回http_body
        if ($this->result_mode==1)
        {
            curl_setopt($this->ch,CURLOPT_NOBODY,1);
        }
        else
        {
            curl_setopt($this->ch,CURLOPT_NOBODY,0);
        }
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->ch, CURLOPT_VERBOSE, 0);
        //设置请求http头request_header
        if(!empty($headers))
        {
            curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
        }
        else
        {
            curl_setopt($this->ch, CURLOPT_HTTPHEADER, []);
            
        }
        if($mode)
        {        
            $fields_string = http_build_query($data);
            curl_setopt($this->ch, CURLOPT_POST, true);
            curl_setopt($this->ch, CURLOPT_BINARYTRANSFER, true);
            curl_setopt($this->ch, CURLOPT_POSTFIELDS, $fields_string);
        }
        else
        {
            curl_setopt($this->ch, CURLOPT_POST, false);
            curl_setopt($this->ch, CURLOPT_BINARYTRANSFER, false);
        }
	if (!empty($this->proxy))
	{
	    curl_setopt($this->ch, CURLOPT_PROXY,$this->proxy);
        }
        if((!empty($this->proxyport)) && (!empty($this->proxy)))
        {
            curl_setopt($this->ch,CURLOPT_PROXYPORT,$this->proxyport);
        }
        if ($ssl)
        {
            curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER,false);
            curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST,false);
        }            
        $response = curl_exec($this->ch);
        if ($response)
        {
            if ($this->result_mode==3)
            {
                $header_size = curl_getinfo($this->ch, CURLINFO_HEADER_SIZE);
                $header_string = substr($response, 0, $header_size);
                $body = substr($response, $header_size);
                $header_rows = explode(PHP_EOL, $header_string);
                $header_rows = array_filter($header_rows);
                $i=0;
                $j=0;
                foreach((array)$header_rows as $hr)
                {
                    $colonpos = strpos($hr, ':');
                    $key = $colonpos !== false ? substr($hr, 0, $colonpos) : (int)$i++;
                    $headers[$key] = $colonpos !== false ? trim(substr($hr, $colonpos+1)) : $hr;
                }
                foreach((array)$headers as $key => $val)
                {
                    $vals = explode(';', $val);
                    if(count($vals) >= 2)
                    {
                        unset($headers[$key]);
                        foreach($vals as $vk => $vv)
                        {
                            $equalpos = strpos($vv, '=');
                            $vkey = $equalpos !== false ? trim(substr($vv, 0, $equalpos)) : (int)$j++;
                            $headers[$key][$vkey] = $equalpos !== false ? trim(substr($vv, $equalpos+1)) : $vv;
                        }
                    }
            
                }
                return ["header"=>$headers,"body"=>$body];
            }
            else
            {
                return $response;
            }
        }
        else
        {
            $this->errormsg[]=curl_error($this->ch);
            return false;
        }
    }
    public function setresult($mode=0)
    {
        $this->result_mode=$mode;
    }
    public function geterror()
    {
        return $this->errormsg;
    }
    public function httpget($url,$headers=[])        //封装http的get方法
    {
        return $this->base($url, $headers=[], $mode=false, $data=[], $ssl=false, $timeout=0);
    }
    public function httppost($url,$data,$headers=[])  //封装http的post方法
    {
        return $this->base($url, $headers, $mode=true, $data, $ssl=false, $timeout=0);
    }
    public function httpspost($url,$data,$headers=[])
    {
        return $this->base($url, $headers, $mode=true, $data, $ssl=true, $timeout=0);
    }
    public function __destruct()
    {
        curl_close($this->ch);
    }
	public function R($URL,$DATE=array(),$TYPE='',$DIP='',$header=''){
        $TYPE=isset($TYPE)?$TYPE:'GET';//请求方式
        $CURL=curl_init();//开启Curl服务
        curl_setopt($CURL, CURLOPT_URL,$URL);//设置请求地址
        curl_setopt($CURL, CURLOPT_HEADER, 0); //返回头部
        curl_setopt($CURL, CURLOPT_RETURNTRANSFER, 1); //返回信息  
        curl_setopt($CURL, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($CURL, CURLOPT_CONNECTTIMEOUT, 1); //连接等待时间
        curl_setopt($CURL, CURLOPT_TIMEOUT, 5);//连接超时时间
        curl_setopt($CURL, CURLOPT_SSL_VERIFYPEER, false); //对认证证书来源的检查
        curl_setopt($CURL, CURLOPT_SSL_VERIFYHOST, false); //从证书中检查SSL加密算法是否存在
        if($DIP){
            $D_IP=explode(':',$DIP);
            curl_setopt($CURL, CURLOPT_PROXY, $D_IP[0]); //代理服务器地址
            curl_setopt($CURL, CURLOPT_PROXYPORT,$D_IP[1]); //代理服务器端口
        }
        curl_setopt($CURL, CURLOPT_ENCODING,'gzip');
        if(strtoupper($TYPE)=='POST'){   
            curl_setopt($CURL, CURLOPT_POST, 1);//设置为POST方式    
            curl_setopt($CURL, CURLOPT_POSTFIELDS, http_build_query($DATE));
        }
        if($header){
            curl_setopt($CURL, CURLOPT_HTTPHEADER, $header);
        }
        $res = curl_exec($CURL);
        $curl_errno = curl_errno($CURL);
        if($curl_errno){
            curl_setopt($CURL, CURLOPT_CONNECTTIMEOUT_MS, 1);//重新连接时间
        }
        curl_close($CURL);
        return $res;
    }
}